package net.tt.util;

import pub.tbc.toolkit.Objs;
import pub.tbc.toolkit.function.BiConsumer;
import pub.tbc.toolkit.function.Consumer;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * 基于函数回调提供更快捷方便的循环功能
 *
 * @author tbc
 * @version 1.0 {2016年8月2日 下午6:04:14}
 */
public class Loops {

    private Loops() {
        throw new AssertionError("No pub.tbc.toolkit.Loops instances for you!");
    }

    public static void times(int end, Consumer<Integer> consumer) {
        upto(0, end, consumer);
    }

    public static void upto(int start, int end, Consumer<Integer> consumer) {
        step(start, end, 1, consumer);
    }

    /**
     * 从start（含）到end（不含）遍历，每次加step
     *
     * @param start
     * @param end
     * @param step
     * @param consumer
     */
    public static void step(int start, int end, int step, Consumer<Integer> consumer) {
        if (start > end) {
            end = start + end;
            start = end - start;
            end = end - start;
        }

        for (int i = start; i < end; i += step) {
            consumer.accept(i);
        }
    }

    public static <T> void forEach(T[] ts, Consumer<T> consumer) {
        if (pub.tbc.toolkit.Objs.isEmpty(ts)) {
            return;
        }
        for (T t : ts) {
            consumer.accept(t);
        }
    }

    public static <T> void forEach(Collection<T> collection, Consumer<T> consumer) {
        if (pub.tbc.toolkit.Objs.isEmpty(collection)) {
            return;
        }
        for (T t : collection) {
            consumer.accept(t);
        }
    }

    public static <K, V> void forEach(Map<K, V> map, BiConsumer<K, V> biConsumer) {
        if (Objs.isEmpty(map)) {
            return;
        }
        Set<K> keys = map.keySet();
        for (K k : keys) {
            biConsumer.accept(k, map.get(k));
        }
    }

    public static <T> T filter(Iterable<T> iterable) {
        // TODO... 参考, FluentIterable filter
        return null;
    }

    public static <T, R> R map(Iterator<T> iterator) {
        // TODO... FluentIterable transform
        return null;
    }

    public static <T> T folds(Iterator<T> iterator) {
        // TODO...
        return null;
    }

    public static <T extends Number> T sum(Iterator<T> numbers) {

        return null;
    }

    public static void main(String[] args) {
        pub.tbc.toolkit.Loops.times(9, new Consumer<Integer>() {
            public void accept(Integer t) {
                System.out.println(t);
            }
        });

        pub.tbc.toolkit.Loops.step(10, 100, 10, new Consumer<Integer>() {
            public void accept(Integer t) {
                System.out.println(t);
            }
        });
    }

}
